<?php

namespace app\service;

use think\facade\Config;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use util\Logger;

class DeepSeekService
{
    protected Client $client;
    protected array $config;

    public function __construct()
    {
        $api_key      = \app\admin\model\Config::where('name', 'ai_key')->value('value');
        $this->config = [
            'api_key'  => $api_key,
            'base_url' => 'https://api.deepseek.com/v1',
            'model'    => 'deepseek-chat',
        ];
        $this->client = new Client([
            'base_uri' => $this->config['base_url'],
            'timeout'  => 3600,
        ]);
    }

    private function getHeaders()
    {
        return [
            'Content-Type'  => 'application/json',
            'Accept'        => 'application/json',
            'Authorization' => 'Bearer ' . $this->config['api_key'],
        ];
    }

    /**
     * 流式调用
     * @param array $messages
     * @param callable $callback
     * @return bool|string
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function streamChatCompletion(array $messages, callable $callback)
    {
        try {
            $response = $this->client->post('/chat/completions', [
                'headers' => $this->getHeaders(),
                'json'    => [
                    'model'       => $this->config['model'],
                    'messages'    => $messages,
                    'temperature' => 0.8,
                    'stream'      => true
                ],
                'stream'  => true
            ]);

            $stream      = $response->getBody();
            $fullContent = '';
            while (!$stream->eof()) {
                $chunk = $stream->read(1024);
                $lines = explode("\n", $chunk);

                foreach ($lines as $line) {
                    $cleanLine = trim($line);
                    if (strpos($cleanLine, 'data: ') === 0) {
                        $jsonStr = substr($cleanLine, 5);
                        if ($jsonStr === '[DONE]') {
                            $callback('', true);
                            return true;
                        }

                        $data              = json_decode($jsonStr, true);
                        $reasoning_content = $data['choices'][0]['delta']['reasoning_content'] ?? '';
                        if (!empty($reasoning_content)) {
                            $callback('', false, $reasoning_content);
                        }
                        $content = $data['choices'][0]['delta']['content'] ?? '';
                        if (!empty($content)) {
                            $fullContent .= $content;
                            $callback($content, false);
                        }
                    }
                }
            }

            return $fullContent;
        } catch (RequestException $e) {
            $callback('服务请求失败: ' . $e->getMessage(), true);
            return false;
        }
    }

    /**
     * 生成标题
     * @param string $message
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function generateTitle(string $message)
    {
        try {
            $response = $this->client->post('/chat/completions', [
                'headers' => $this->getHeaders(),
                'json'    => [
                    'model'       => 'deepseek-chat',
                    'messages'    => [['role' => 'user', 'content' => "请为以下对话生成一个简短的中文标题，不要使用任何标点符号，不超过15个字：\n" . $message]],
                    'temperature' => 0.8,
                ]
            ]);

            $body = json_decode($response->getBody(), true);
            return [
                'success' => true,
                'title'   => $body['choices'][0]['message']['content'] ?? '',
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'error'   => $e->getMessage(),
                'code'    => $e->getCode()
            ];
        }
    }

    public function createChatCompletion(array $messages)
    {
        try {
            $response = $this->client->post('/chat/completions', [
                'headers' => $this->getHeaders(),
                'json'    => [
                    'model'       => $this->config['model'],
                    'messages'    => $messages,
                    'temperature' => 0.8,
                ]
            ]);

            $body = json_decode($response->getBody(), true);
            return [
                'success'           => true,
                'reasoning_content' => $body['choices'][0]['message']['reasoning_content'] ?? '',
                'content'           => $body['choices'][0]['message']['content'] ?? '',
                'full_response'     => $body
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'error'   => $e->getMessage(),
                'code'    => $e->getCode()
            ];
        }
    }

}
